home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1999 July / Macworld (1999-07).dmg / Shareware World / Info / For Developers / Mops 3.4.sea / Mops source / SpeechStuff folder / SpeechMgr < prev    next >
Text File  |  1993-08-21  |  13KB  |  755 lines

  1. \ Speech Manager support code and classes.
  2. \
  3. \ The Speech Manager is not currently in ROM.  To utilize this class, you
  4. \ will have to obtain the Macintosh Speech Manager from an appropriate
  5. \ source.  (sources I know of: ftp via ftp.apple.com, develop CD)
  6. \
  7.  
  8. need Gestalt
  9.  
  10. : gestaltSpeechAttr 'type ttsc ;
  11.  
  12. 0 constant gestaltSpeechMgrPresent
  13.  
  14. : kTextToSpeechSynthType 'type ttsc ;
  15. : kTextToSpeechVoiceType 'type ttvd ;
  16. : kTextToSpeechVoiceFileType 'type ttvf ;
  17. : kTextToSpeechVoiceBundleType 'type ttvb ;
  18.  
  19. \ Speech Manager error codes
  20. -240 constant noSynthFound
  21. -241 constant synthOpenFailed
  22. -242 constant synthNotReady
  23. -243 constant bufTooSmall
  24. -244 constant voiceNotFound
  25. -245 constant incompatibleVoice
  26. -246 constant badDictFormat
  27. -247 constant badPhonemeText
  28.  
  29. \ constants for SpeakBuffer and text done callback
  30. 1 constant kNoEndingProsody
  31. 2 constant kNoSpeechInterrupt
  32. 4 constant kPreFlightThenPause
  33.  
  34. \ constants for StopSpeechAt and PauseSpeechAt
  35. 0 constant kImmediate
  36. 1 constant kEndOfWord
  37. 2 constant kEndOfSentence
  38.  
  39. \ GetSpeechInfo and SetSpeechInfo selectors
  40. : soStatus 'type stat ;
  41. : soErrors 'type erro ;
  42. : soInputMode 'type inpt ;
  43. : soCharacterMode 'type char ;
  44. : soNumberMode 'type nmbr ;
  45. : soRate 'type rate ;
  46. : soPitchBase 'type pbas ;
  47. : soPitchMod 'type pmod ;
  48. : soVolume 'type volm ;
  49. : soSynthType 'type vers ;
  50. : soRecentSync 'type sync ;
  51. : soPhonemeSymbols 'type phsy ;
  52. : soCurrentVoice 'type cvox ;
  53. : soCommandDelimiter 'type dlim ;
  54. : soReset 'type rset ;
  55. : soCurrentA5 'type myA5 ;
  56. : soRefCon 'type refc ;
  57. : soTextDoneCallBack 'type tdcb ;
  58. : soSpeechDoneCallBack 'type sdcb ;
  59. : soSyncCallBack 'type sycb ;
  60. : soErrorCallBack 'type ercb ;
  61. : soPhonemeCallBack 'type phcb ;
  62. : soWordCallBack 'type wdcb ;
  63. : soSynthExtension 'type xtnd ;
  64.  
  65. \ Speaking mode constants
  66. : modeText 'type TEXT ;
  67. : modeTX 'type TX   ;
  68. : modePhonemes 'type PHON ;
  69. : modePH 'type PH   ;
  70. : modeNormal 'type NORM ;
  71. : modeLiteral 'type LTRL ;
  72.  
  73.  
  74. \ GetVoiceInfo selectors
  75. : soVoiceDescription 'type info ;
  76. : soVoiceFile 'type fref ;
  77.  
  78. \ Gender constants
  79. 0 constant kNeuter
  80. 1 constant kMale
  81. 2 constant kFemale
  82.  
  83. 0 value NumOfVoices
  84.     
  85. 345 constant DescriptionLength
  86.  
  87. :CLASS SpeechChannel super{ object }
  88.     longword data
  89.     
  90.     :m get: 
  91.         get: data
  92.         ;m
  93. ;CLASS
  94.  
  95. :CLASS VoiceSpec super{ object }
  96.     var creator
  97.     var id
  98.     
  99.     :m Creator?: ( -- creator )
  100.         get: creator
  101.         ;m
  102.         
  103.     :m id?: ( -- id )
  104.         get: id
  105.         ;m
  106.         
  107. \ Note that Apple recommends against setting these value directly in order
  108. \ to maintain forward compatibility.  Therefore, there are no methods for
  109. \ manually placing these.  Note that if you do include them, you are risking
  110. \ NOT having compatibility with future versions of the Speech Manager.
  111.         
  112. ;CLASS
  113.  
  114. :CLASS VoiceDescription super{ object }
  115.     var Length
  116.     VoiceSpec voice
  117.     var version
  118. 64    bytes name
  119. 256    bytes comment
  120.     int gender
  121.     int    age
  122.     int script
  123.     int language
  124.     int region
  125. 16 bytes reserved
  126.  
  127.     :m Length?: ( -- length )
  128.         get: Length
  129.         ;m
  130.         
  131.     :m VoiceSpec?: ( -- creator id )
  132.         creator?: voice
  133.         id?: voice
  134.         ;m
  135.         
  136.     :m Name?: ( -- ^name ) \ Note: 64 bytes!
  137.         addr: name
  138.         ;m
  139.         
  140.     :m Comment?: ( -- ^str255 ) \ Pass the pointer to this
  141.         addr: comment
  142.         ;m
  143.         
  144.     :m Gender?: ( -- w ) \ 0 neutral 1 male 2 female
  145.         get: gender
  146.         ;m
  147.         
  148.     :m Age?: ( -- w )
  149.         get: age
  150.         ;m
  151.         
  152.     :m Script?: ( -- w )
  153.         get: script
  154.         ;m
  155.         
  156.     :m Language?: ( -- w )
  157.         get: language
  158.         ;m
  159.         
  160.     :m Region?: ( -- w )
  161.         get: region
  162.         ;m
  163.         
  164. ;CLASS
  165.  
  166. :CLASS VoiceFileInfo super{ object }
  167.     \ FSSpec type taken from class file.
  168.     object        FSSpec \ Use as a placeholder
  169.     int            FSvRefNum
  170.     var            FSDirID
  171. 64    bytes        FileName
  172.     int resID
  173.     
  174.     :m ^FSSpec?: ( -- ^FSSpec )
  175.         addr: FSSpec
  176.         ;m
  177.         
  178.     :m VolumeID?: ( -- n )
  179.         get: FSvRefNum
  180.         ;m
  181.         
  182.     :m DirID?: ( -- n )
  183.         get: FSDirID
  184.         ;m
  185.         
  186.     :m ^Filename?: ( -- ^fname )
  187.         addr: FileName
  188.         ;m
  189.         
  190.     :m ResourceID#?: ( -- n )
  191.         get: resID
  192.         ;m
  193.         
  194. ;CLASS
  195.  
  196. :CLASS SpeechStatusInfo super{ object }
  197. 1     bytes outputBusy
  198. 1    bytes outputPaused
  199. 4    bytes inputBytesLeft
  200. 2    bytes phonemeCode
  201.     
  202.     :m Busy?: ( -- n )
  203.         addr: outputBusy c@x
  204.         ;m
  205.         
  206.     :m Paused?: ( -- n )
  207.         addr: outputPaused c@x
  208.         ;m
  209.         
  210.     :m BytesLeft?: ( -- n )
  211.         addr: inputBytesLeft @
  212.     ;m
  213.         
  214.     :m Code?: ( -- n )
  215.         addr: phonemeCode w@x
  216.         ;m
  217. ;CLASS
  218.  
  219. :CLASS SpeechErrorInfo super{ object }
  220.     int    count
  221.     int    oldest
  222.     var    oldPos
  223.     int    newest
  224.     var    newPos
  225.     
  226.     :m count?: ( -- n )
  227.         get: count
  228.         ;m
  229.         
  230.     :m oldest?: ( -- n )
  231.         get: oldest
  232.         ;m
  233.         
  234.     :m oldPosition?: ( -- n )
  235.         get: oldPos
  236.         ;m
  237.         
  238.     :m newest?: ( -- n )
  239.         get: newest
  240.         ;m
  241.         
  242.     :m newPosition?: ( -- n )
  243.         get: newPos
  244.         ;m
  245. ;CLASS
  246.  
  247. :CLASS SpeechVersionInfo super{ object }
  248.     var synthType
  249.     var synthSubType
  250.     var synthManufacturer
  251.     var synthFlags
  252. 7    bytes synthVersion
  253.  
  254.     :m type?: ( -- n )
  255.         get: synthType
  256.         ;m
  257.         
  258.     :m subType?: ( -- n )
  259.         get: synthSubType
  260.         ;m
  261.         
  262.     :m Manufacturer?: ( -- n )
  263.         get: synthManufacturer
  264.         ;m
  265.         
  266.     :m Flags?: ( -- n )
  267.         get: synthFlags
  268.         ;m
  269.         
  270. \ Note: all of the above have been converted from their assembly 4 bytes
  271. \ to vars.  The feeling is that any decoding that might have to be done on
  272. \ such things can be done by the parent program.
  273.  
  274.     :m ^version?: ( -- ^version )
  275.         addr: synthVersion
  276.         ;m
  277.         
  278. ;CLASS
  279.  
  280. :CLASS PhonemeInfo super{ object }
  281.     int opcode
  282. 16    bytes phStr
  283. 32    bytes exampleStr
  284.     int hiliteStart
  285.     int hiliteEnd
  286.     
  287.     :m opcode?: ( -- n )
  288.         get: opcode
  289.         ;m
  290.         
  291.     :m ^String: ( -- ^string )
  292.         addr: phStr
  293.         ;m
  294.         
  295.     :m ^example: ( -- ^exampleString )
  296.         addr: exampleStr
  297.         ;m
  298.         
  299.     :m Start?: ( -- n )
  300.         get: hiliteStart
  301.         ;m
  302.         
  303.     :m End?: ( -- n )
  304.         get: hiliteEnd
  305.         ;m
  306.     
  307. ;CLASS
  308.  
  309. :CLASS PhonemeDescriptor super{ object }
  310.     int phonemeCount
  311.     phonemeInfo thePhonemes
  312.     
  313.     :m HowMany?: ( -- n )
  314.         get: phonemeCount
  315.         ;m
  316.         
  317.     :m ^thesePhonemes: ( -- ^phonemeInfo )
  318.         addr: thePhonemes
  319.         ;m
  320.         
  321. ;CLASS
  322.  
  323. :CLASS SpeechXtndData super{ object }
  324.     var synthCreator
  325.     int synthData
  326.     
  327.     :m Creator?: ( -- n )
  328.         get: synthCreator
  329.         ;m
  330.         
  331.     :m Data?: ( -- n )
  332.         get: synthData
  333.         ;m
  334.         
  335.     :m putCreator: ( n -- )
  336.         put: synthCreator
  337.         ;m
  338.         
  339.     :m putData: ( n -- )
  340.         put: synthData
  341.         ;m
  342.         
  343. ;CLASS
  344.  
  345. :CLASS DelimiterInfo super{ object } \ defaults to "[[" and "]]"
  346. 2     bytes startDelimiter
  347. 2    bytes endDelimiter
  348.  
  349.     :m setStart: ( c1 c2 -- )
  350.         addr: startDelimiter dup 1+ rot swap c! c!
  351.         ;m
  352.         
  353.     :m setEnd: ( c1 c2 -- )
  354.         addr: endDelimiter dup 1+  swap c! c!
  355.         ;m
  356. ;CLASS
  357.  
  358. \ OSErr - word
  359. \ OSType - var
  360.  
  361. : SpeechManagerVersion
  362.     word0
  363.     call SpeechManagerVersion
  364.     i->l
  365.     ;
  366.     
  367. : IsMySpeechBusy? ( -- n )
  368.     word0
  369.     call SpeechBusy
  370.     i->l
  371.     ;
  372.     
  373. : IsAnySpeechBusy? ( -- n )
  374.     word0
  375.     call SpeechBusySystemWide
  376.     i->l
  377.     ;
  378.     
  379. \ : Voices? ( -- rc ) \ Number of available voices
  380. \    0 -> NumOfVoices
  381. \    word0
  382. \    ['] NumOfVoices
  383. \    call CountVoices
  384. \    i->l
  385. \    ;
  386.     
  387.     
  388. :CLASS Talker super{ object }
  389.     string myString
  390.     string phonemebuf
  391.     var    phonemeBufLength
  392.     voiceSpec voice
  393.     voiceDescription voiceInfo
  394.     handleList channels
  395.     Objhandle myInfo
  396.     handlelist myInfoList
  397.     handleList tempList
  398.     longword temp
  399.     int voiceCount
  400.     
  401.     
  402.     :m new:
  403.         release: channels
  404.         release: myInfoList
  405.         ;m
  406.         
  407.     :m put: ( addr len -- )
  408.         put: myString
  409.         ;m
  410.         
  411.     :m get: ( addr len -- )
  412.         get: myString
  413.         ;m
  414.     
  415.     :m SayIt: ( -- rc )
  416.         word0 \ Save room for rc
  417.         get: MyString str255
  418.         call SpeakString
  419.         i->l
  420.         ;m
  421.         
  422.     :m SetVoice: { creator id -- rc }
  423.         word0
  424.         creator makeint
  425.         id makeint
  426.         addr: voice \ get the pointer
  427.         call MakeVoiceSpec
  428.         i->l
  429.         ;m
  430.         
  431.     :m Voices: ( -- rc voices )
  432.         word0
  433.         addr: voiceCount
  434.         call CountVoices
  435.         i->l
  436.         get: voiceCount
  437.         ;m
  438.         
  439.     :m GetAVoice: { index -- rc }
  440.         index makeint \ Will leave room for return code
  441.         addr: voice
  442.         call GetIndVoice
  443.         i->l
  444.         ;m
  445.         
  446.     :m GetVoiceDescription: ( -- rc )
  447.         word0
  448.         addr: voice
  449.         addr: voiceInfo
  450.         DescriptionLength
  451.         call GetVoiceDescription
  452.         i->l
  453.         ;m
  454.         
  455.     :m NewChannel: ( -- rc )
  456.         word0
  457.         addr: voice
  458.         ['] SpeechChannel newObj: channels
  459.         obj: channels
  460.         call NewSpeechChannel
  461.         i->l
  462.         ;m
  463.         
  464.     :m DisposeChannel: { channel -- rc }
  465.         word0
  466.         channel select: channels
  467.         obj: channels get: **
  468.         call DisposeSpeechChannel
  469.         i->l
  470.         channel select: channels removeObj: channels
  471.         ;m
  472.         
  473.     :m SpeakToChannel: { channel -- rc }
  474.         word0
  475.         channel select: channels
  476.         obj: channels get: **
  477.         get: myString
  478.         call SpeakText
  479.         i->l
  480.         ;m
  481.         
  482.     :m Halt: { channel -- rc }
  483.         word0
  484.         channel select: channels
  485.         obj: channels get: **
  486.         call StopSpeech
  487.         i->l
  488.         ;m
  489.         
  490.     :m SetRate: { channel whole fraction -- rc }
  491.         word0
  492.         channel select: channels
  493.         obj: channels get: **
  494.         whole fraction pack
  495.         call setSpeechRate
  496.         i->l
  497.         ;m
  498.     
  499.     :m GetRate: { channel -- rc whole fraction }
  500.         word0
  501.         channel select: channels
  502.         obj: channels get: **
  503.         addr: temp
  504.         call getSpeechRate
  505.         i->l
  506.         get: temp
  507.         unpack
  508.         ;m
  509.         
  510.     :m SetPitch: { channel whole fraction -- rc }
  511.         word0
  512.         channel select: channels
  513.         obj: channels get: **
  514.         whole fraction pack
  515.         call setSpeechPitch
  516.         i->l
  517.         ;m
  518.  
  519.     :m GetPitch: { channel -- rc whole fraction }
  520.         word0
  521.         channel select: channels
  522.         obj: channels get: **
  523.         addr: temp
  524.         call getSpeechPitch
  525.         i->l
  526.         get: temp
  527.         unpack
  528.         ;m
  529.  
  530.     :m Stop: { channel whereToStop -- rc } \ 0 = now, 1 eow, 2 eos
  531.         word0
  532.         channel select: channels
  533.         obj: channels get: **
  534.         whereToStop
  535.         call StopSpeechAt
  536.         i->l
  537.         ;m
  538.         
  539.     :m Pause: { channel whereToPause -- rc } \ 0 now, 1 eow, 2 eos
  540.         word0
  541.         channel select: channels
  542.         obj: channels get: **
  543.         whereToPause
  544.         call PauseSpeechAt
  545.         i->l
  546.         ;m
  547.         
  548.     :m Continue: { channel -- rc }
  549.         word0
  550.         channel select: channels
  551.         obj: channels get: **
  552.         call ContinueSpeech
  553.         i->l
  554.         ;m
  555.         
  556.     :m SpeakWithOptions: { channel flags -- rc }
  557.         word0
  558.         channel select: channels
  559.         obj: channels get: **
  560.         get: myString
  561.         flags
  562.         call SpeakBuffer
  563.         i->l
  564.         ;m
  565.         
  566.     :m TextToPhonemes: { channel -- rc }
  567.         clear: phonemeBuf 
  568.         32000 dup put: phonemeBufLength setSize: phonemeBuf
  569.         word0
  570.         channel select: channels
  571.         obj: channels get: **
  572.         get: myString
  573.         handle: phonemeBuf addr: phonemeBufLength
  574.         call TextToPhonemes
  575.         i->l
  576.         get: phonemeBufLength
  577.         setsize: phonemeBuf
  578.         ;m
  579.         
  580.     :m getPhonemes: ( -- addr len )
  581.         get: phonemeBuf
  582.         ;m
  583.         
  584.         
  585.     :m GetInfo: { channel selector -- rc ^obj }
  586.         releaseObj: myInfo
  587.         selector
  588.         case
  589.             soStatus of 
  590.                 ['] SpeechStatusInfo  newObj: myInfo
  591.             endof
  592.             soErrors of 
  593.                 ['] SpeechErrorInfo newObj: myInfo
  594.             endof
  595.             soInputMode of 
  596.                 ['] var newObj: myInfo 
  597.             endof
  598.             soCharacterMode of 
  599.                 ['] var newObj: myInfo 
  600.             endof
  601.             soNumberMode of 
  602.                 ['] var newObj: myInfo 
  603.             endof
  604.             soRate of 
  605.                 ['] var newObj: myInfo 
  606.             endof
  607.             soPitchBase of 
  608.                 ['] var newObj: myInfo 
  609.             endof
  610.             soPitchMod of 
  611.                 ['] var newObj: myInfo 
  612.             endof
  613.             soVolume of 
  614.                 ['] var newObj: myInfo 
  615.             endof
  616.             soSynthType of 
  617.                 ['] SpeechVersionInfo newObj: myInfo 
  618.             endof
  619.             soRecentSync of 
  620.                 ['] var newObj: myInfo 
  621.             endof
  622.             soPhonemeSymbols of 
  623.                 ['] phonemeDescriptor newObj: myInfo 
  624.             endof
  625.             soSynthExtension of 
  626.                 ['] SpeechXtndData newObj: myInfo 
  627.             endof
  628.             ." Big trouble... no match"
  629.         endcase
  630.         word0
  631.         channel select: channels
  632.         obj: channels get: **
  633.         selector
  634.         obj: myInfo
  635.         call GetSpeechInfo
  636.         i->l
  637.         obj: myInfo
  638.         ;m
  639.         
  640. private
  641.         
  642.     :m CallSetInfo: { channel selector -- rc }
  643.         word0
  644.         channel select: channels
  645.         obj: channels get: **
  646.         selector
  647.         obj: myInfo
  648.         call SetSpeechInfo
  649.         i->l
  650.         ;m
  651.         
  652.     :m SetUpSpeechInfoObject: { channel selector -- }
  653.         clear: myInfo
  654.         selector
  655.         case
  656.             soInputMode of 
  657.                 ['] var newObj: myInfo 
  658.             endof
  659.             soCharacterMode of 
  660.                 ['] var newObj: myInfo 
  661.             endof
  662.             soNumberMode of 
  663.                 ['] var newObj: myInfo 
  664.             endof
  665.             soRate of 
  666.                 ['] var newObj: myInfo 
  667.             endof
  668.             soPitchBase of 
  669.                 ['] var newObj: myInfo 
  670.             endof
  671.             soPitchMod of 
  672.                 ['] var newObj: myInfo 
  673.             endof
  674.             soVolume of 
  675.                 ['] var newObj: myInfo 
  676.             endof
  677.             soCurrentVoice of 
  678.                 ['] VoiceSpec newObj: myInfo 
  679.             endof
  680.             soCommandDelimiter of 
  681.                 ['] DelimiterInfo newObj: myInfo 
  682.             endof
  683.             soReset of 
  684.                 ['] var newObj: myInfo 
  685.             endof
  686.             soCurrentA5 of 
  687.                 ['] var newObj: myInfo 
  688.             endof
  689.             soRefCon of 
  690.                 ['] var newObj: myInfo 
  691.             endof
  692.             soTextDoneCallBack of 
  693.                 ['] var newObj: myInfo 
  694.             endof
  695.             soSpeechDoneCallBack of 
  696.                 ['] var newObj: myInfo 
  697.             endof
  698.             soSyncCallBack of 
  699.                 ['] var newObj: myInfo 
  700.             endof
  701.             soErrorCallBack of 
  702.                 ['] var newObj: myInfo 
  703.             endof
  704.             soPhonemeCallBack of 
  705.                 ['] var newObj: myInfo 
  706.             endof
  707.             soWordCallBack of 
  708.                 ['] var newObj: myInfo 
  709.             endof
  710.             soSynthExtension of 
  711.                 ['] SpeechXtndData newObj: myInfo 
  712.             endof
  713.             ." Big trouble... no match"
  714.         endcase
  715.         ;m
  716.         
  717. public
  718.         
  719.     :m SetInfo: { channel selector -- rc }
  720.         channel selector setupSpeechInfoObject: self
  721.         channel selector callSetInfo: self
  722.         ;m
  723.         
  724.     :m Dictionary: { channel dichandle -- }
  725.         word0
  726.         channel select: channels
  727.         obj: channels get: **
  728.         dichandle
  729.         call UseDictionary
  730.         i->l
  731.         ;m
  732.         
  733.     :m VoiceInfo: { selector -- rc ^obj }
  734.         selector soVoiceDescription = 
  735.         if
  736.             ['] VoiceDescription newObj: myInfo
  737.         else 
  738.             selector soVoiceFile = 
  739.             if
  740.                 ['] VoiceFileInfo newObj: myInfo
  741.             else
  742.                 ." No Match" exit
  743.             then
  744.         then
  745.         addr: voice
  746.         selector
  747.         obj: myInfo
  748.         call GetVoiceInfo
  749.         i->l
  750.         obj: myInfo
  751.         ;m
  752.         
  753.         
  754. ;CLASS
  755.